/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <android/log.h>

#include "stream/InputStream.h"

#include "WavFmtChunkHeader.h"

static const char *TAG = "WavFmtChunkHeader";

namespace parselib {

    const RiffID WavFmtChunkHeader::RIFFID_FMT = makeRiffID('f', 'm', 't', ' ');

    WavFmtChunkHeader::WavFmtChunkHeader() : WavChunkHeader(RIFFID_FMT) {
        mEncodingId = ENCODING_PCM;
        mNumChannels = 0;
        mSampleRate = 0;
        mAveBytesPerSecond = 0;
        mBlockAlign = 0;
        mSampleSize = 0;
        mExtraBytes = 0;
    }

    WavFmtChunkHeader::WavFmtChunkHeader(RiffID tag) : WavChunkHeader(tag) {
        mEncodingId = ENCODING_PCM;
        mNumChannels = 0;
        mSampleRate = 0;
        mAveBytesPerSecond = 0;
        mBlockAlign = 0;
        mSampleSize = 0;
        mExtraBytes = 0;
    }

    void WavFmtChunkHeader::normalize() {
        if (mEncodingId == ENCODING_PCM || mEncodingId == ENCODING_IEEE_FLOAT) {
            mBlockAlign = (short) (mNumChannels * (mSampleSize / 8));
            mAveBytesPerSecond = mSampleRate * mBlockAlign;
            mExtraBytes = 0;
        } else {
            //hmmm....
        }
    }

    void WavFmtChunkHeader::read(InputStream *stream) {
        WavChunkHeader::read(stream);
        stream->read(&mEncodingId, sizeof(mEncodingId));
        stream->read(&mNumChannels, sizeof(mNumChannels));
        stream->read(&mSampleRate, sizeof(mSampleRate));
        stream->read(&mAveBytesPerSecond, sizeof(mAveBytesPerSecond));
        stream->read(&mBlockAlign, sizeof(mBlockAlign));
        stream->read(&mSampleSize, sizeof(mSampleSize));

        if ((mEncodingId != ENCODING_PCM && mEncodingId != ENCODING_IEEE_FLOAT) ||
            (mChunkSize != 16)) {
            // only read this if NOT PCM
            stream->read(&mExtraBytes, sizeof(mExtraBytes));
        } else {
            mExtraBytes = (short) (mChunkSize - 16);
        }
    }

} // namespace parselib
